package im.oen.boot.api.dispatch.handler;

import im.oen.boot.api.annotation.handler.MethodAroundHandler;
import im.oen.boot.api.dao.AbsDao;
import im.oen.boot.api.entity.AbsEntity;
import im.oen.boot.common.data.Page;
import im.oen.boot.common.utils.JsonUtil;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.PageRequest;

import java.io.Serializable;

/**
 * @author Kevin.Xu
 */
public class PageMethodHandler implements MethodHandler {
    @Override
    public String cmd() {
        return "page";
    }

    @Override
    public <T extends AbsEntity, ID extends Serializable> Object handler(AbsDao<T, ID> dao, MethodAroundHandler<T> methodAroundHandler, Class<T> entity, String[] paths, String body) {
        boolean emptyHandler = methodAroundHandler == null;
        Page.Request<T> data = JsonUtil.safeToObj(body, Page.Request.class, entity);

        Page.Result<T> result = null;
        if (!emptyHandler) {
            methodAroundHandler.pageBefore(data);
            result = methodAroundHandler.overridePage(dao, data);
        }

        if (result == null) {
            PageRequest pageable = PageRequest.of(data.getPage(), data.getSize());
            org.springframework.data.domain.Page<T> page = null;
            if (data.getParam() == null) {
                page = dao.findAll(pageable);
            } else {
                Example example = Example.of(data.getParam());
                page = dao.findAll(example, pageable);
            }

            result = new Page.Result();
            result.setTotal(page.getTotalElements());
            result.setContents(page.getContent());
            result.setPage(pageable.getPageNumber());
            result.setSize(pageable.getPageSize());
        }

        if (!emptyHandler) {
            methodAroundHandler.pageAfter(result);
        }
        return result;
    }

}
